package com.langsheng.lsintell.ui.widget;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

import com.langsheng.lsintell.R;

import java.util.Locale;

/**
 * Created by xuwei on 2017/3/11.
 * 实现自定义倒计时控件，倒计时频率为1秒，最大倒计时长单位为秒
 */
public class LSTimeCountDownView extends View {

    private Paint mPaint;
    private int mRoundBackColor;
    private int mRoundProgressColor;
    private float mRoundBackWidth;
    private float mRoundProgressWidth;
    private int mTextColor;
    private float mTextSize;
    private float mSmallRoundRadius;
    private int mProgressMax;
    private int progress;
    private float mCurrentAngle;
    private float mRadius;
    private boolean mIsShowSmallCircle = false;
    private RectF mRectF;
    private Thread mTimeCountThread;

    public LSTimeCountDownView(Context context) {
        this(context, null);
    }

    public LSTimeCountDownView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public LSTimeCountDownView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mPaint = new Paint();
        TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.LSTimeCountDownView);
        mRadius = mTypedArray.getDimension(R.styleable.LSTimeCountDownView_radius, 10);
        mRectF = new RectF(0, 0, mRadius * 2, mRadius * 2);
        mRoundBackColor = mTypedArray.getColor(R.styleable.LSTimeCountDownView_roundBackColor, 0xFFFFFF);
        mRoundProgressColor = mTypedArray.getColor(R.styleable.LSTimeCountDownView_roundProgressColor, 0x000000);
        mTextColor = mTypedArray.getColor(R.styleable.LSTimeCountDownView_topTextColor, 0xFFFFFF);
        mTextSize = mTypedArray.getDimension(R.styleable.LSTimeCountDownView_topTextSize, 15);
        mRoundBackWidth = mTypedArray.getDimension(R.styleable.LSTimeCountDownView_roundBackWidth, 5);
        mRoundProgressWidth = mTypedArray.getDimension(R.styleable.LSTimeCountDownView_roundProgressWidth, 5);
        mSmallRoundRadius = mTypedArray.getDimension(R.styleable.LSTimeCountDownView_smallRoundRadius, 6);
        mProgressMax = mTypedArray.getInteger(R.styleable.LSTimeCountDownView_max, 0);
        progress = mProgressMax;
        mTypedArray.recycle();
    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.save();
        canvas.translate(getPaddingLeft(), getPaddingTop());
        //第一个圆弧
        mPaint.setColor(mRoundBackColor);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(mRoundBackWidth);
        mPaint.setAntiAlias(true);
        RectF oval1 = mRectF;
        canvas.drawArc(oval1, -90, 360, false, mPaint);
        //进度圆弧
        mPaint.setStrokeWidth(mRoundProgressWidth);
        mPaint.setColor(mRoundProgressColor);
        canvas.drawArc(mRectF, -90, 360 * mCurrentAngle, false, mPaint);

        mPaint.setStrokeWidth(0);
        mPaint.setColor(mTextColor);
        mPaint.setTextSize(mTextSize);
        int sec = progress % 60;
        int min = progress / 60 % 60;
        int hour = progress / 60 / 60 % 60;
        String tip = "";
        if (hour > 0) {
            tip += String.format(Locale.getDefault(), "%02d", hour) + ":";
        }
        tip += String.format(Locale.getDefault(), "%02d", min) + ":" + String.format(Locale.getDefault(), "%02d", sec);
        float textWidth = mPaint.measureText(tip);
        Paint.FontMetrics fm = mPaint.getFontMetrics();

        canvas.drawText(tip, mRadius - textWidth / 2, mRadius - (fm.ascent + fm.descent) / 2, mPaint);

        if (mIsShowSmallCircle) {
            mPaint.setAntiAlias(true);
            mPaint.setDither(true);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setColor(mRoundProgressColor);
            canvas.drawCircle(mRadius, 0, mSmallRoundRadius, mPaint);

            mPaint.setAntiAlias(true);
            mPaint.setDither(true);
            mPaint.setStyle(Paint.Style.FILL);
            mPaint.setColor(mRoundProgressColor);
            float currentDegreeFlag = 360 * mCurrentAngle;
            float smallCircleX, smallCircleY;
            float radian = (float) Math.abs(Math.PI * currentDegreeFlag / 180);//Math.abs：绝对值 ，Math.PI：表示π ， 弧度 = 度*π / 180
            smallCircleX = (float) Math.abs(Math.sin(radian) * mRadius + mRadius);
            smallCircleY = (float) Math.abs(mRadius - Math.cos(radian) * mRadius);
            canvas.drawCircle(smallCircleX, smallCircleY, mSmallRoundRadius, mPaint);
        }
        canvas.restore();

    }

    public void setProgressColor(int color) {
        mRoundProgressColor = color;
    }

    public void startCountDownTime(final OnProgressFinishListener listener) {
        mIsShowSmallCircle = false;
        ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
        //动画时长，让进度条在CountDown时间内正好从0-360走完，这里由于用的是CountDownTimer定时器，倒计时要想减到0则总时长需要多加1000毫秒，所以这里时间也跟着+1000ms
        animator.setDuration(mProgressMax * 1000);
        animator.setInterpolator(new LinearInterpolator());//匀速
        animator.setRepeatCount(0);//表示不循环，-1表示无限循环
        //值从0-1.0F 的动画，动画时长为countdownTime，ValueAnimator没有跟任何的控件相关联，那也正好说明ValueAnimator只是对值做动画运算，而不是针对控件的，我们需要监听ValueAnimator的动画过程来自己对控件做操作
        //添加监听器,监听动画过程中值的实时变化(animation.getAnimatedValue()得到的值就是0-1.0)
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                /*
                 * 这里我们已经知道ValueAnimator只是对值做动画运算，而不是针对控件的，因为我们设置的区间值为0-1.0f
                 * 所以animation.getAnimatedValue()得到的值也是在[0.0-1.0]区间，而我们在画进度条弧度时，设置的当前角度为360*currentAngle，
                 * 因此，当我们的区间值变为1.0的时候弧度刚好转了360度
                 */
                mCurrentAngle = (float) animation.getAnimatedValue();
                invalidate();//实时刷新view，这样我们的进度条弧度就动起来了
            }
        });
        //开启动画
        animator.start();
        mIsShowSmallCircle = true;
//        还需要另一个监听，监听动画状态的监听器
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                //倒计时结束的时候，需要通过自定义接口通知UI去处理其他业务逻辑
                if (listener != null) {
                    listener.progressFinished();
                }

            }

            @Override
            public void onAnimationCancel(Animator animation) {
            }

            @Override
            public void onAnimationRepeat(Animator animation) {
            }
        });
        countdownMethod();
    }

    //倒计时的方法
    private void countdownMethod() {
        if (mTimeCountThread != null && mTimeCountThread.isAlive()) {
            mTimeCountThread.interrupt();
            progress = mProgressMax;
        }
        mTimeCountThread = new Thread(new Runnable() {

            @Override
            public void run() {
                while (progress > 0) {
                    progress--;
                    postInvalidate();
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        break;
                    }
                }

            }
        });
        mTimeCountThread.start();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize;
        int heightSize;
        int strokeWidth = (int) mRoundProgressWidth;
        if (widthMode != MeasureSpec.EXACTLY) {
            widthSize = getPaddingLeft() + (int) (mRadius * 2) + strokeWidth + getPaddingRight();
            widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, MeasureSpec.EXACTLY);
        }
        if (heightMode != MeasureSpec.EXACTLY) {
            heightSize = getPaddingTop() + (int) (mRadius * 2) + strokeWidth + getPaddingBottom();
            heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, MeasureSpec.EXACTLY);
        }

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    public interface OnProgressFinishListener {
        void progressFinished();
    }
}
